/**
 * 平铺结构转树形结构
 * @param list
 * @param extendProps
 */
import {dynamicObj} from "../types";
import {isType} from "./Judgment";
import {DLS_CONFIG} from "../index";
import {uniqBy} from "ramda";

export function list2Tree (list, extendProps = {}, ) {
    let props = {id: 'id', children: 'children', parentId: 'parentId'}
    Object.assign(props,extendProps)
    list.forEach((parent) => {
        parent.tempChildren = list.filter(child => child[props.parentId] === parent[props.id] && parent[props.id] && child[props.parentId])
        parent.tempChildren.forEach(item => {item._hasParent = true})
        if(parent[props.children]) parent[props.children] = parent[props.children].concat(parent.tempChildren)
        else {
            parent[props.children] = parent.tempChildren
            delete parent.tempChildren
        }
    })
    let result = list.filter(item => !item._hasParent)
    list.forEach(item => {
        delete item._hasParent
    })
    return result
}

/**
 * 为list添加_parentIds属性，属性为不含自身的数组，顺序从最外层开始
 * @param list
 */
export function setParentIds4List(list) {
    list.forEach(data => {
        let parentIds = []
        let nextParentId = data.parentId
        while (nextParentId) {
            parentIds.push(nextParentId)
            let parentNode = list.find(item => item.id === nextParentId)
            if(parentNode) nextParentId = parentNode.parentId
            else nextParentId = null
        }
        data._parentIds = parentIds.reverse()
    })
}

/**
 * 查找树上的点
 */
export function treeFind(treeLike, func) {
    let tree = []
    if(isType('Array', treeLike)) {
        tree = treeLike
    }else if(isType('Object', treeLike)) {
        tree = [treeLike]
    }
    for(let item of tree) {
        if(func(item)) {
            return item
        }
    }
    for(let item of tree) {
        if(item?.children) {
            const nextMatch = treeFind(item.children, func)
            if(nextMatch) return nextMatch
        }
    }
    return null
}

/**
 * 查找节点的父级
 * @param tree
 * @param func
 * @param parent
 */
export function treeFindParent(tree: dynamicObj[], func, parent) {
    for(let item of tree) {
        if(func(item)) {
            return parent
        }
    }
    for(let item of tree) {
        if(item.children) {
            const res = treeFindParent(item.children, func, item)
            if(res) return res
        }
    }
    return null
}

/**
 * 修改树上的点
 */
export function treeMap(treeLike, func) {
    let tree = []
    if(isType('Array', treeLike)) {
        tree = treeLike
    }else if(isType('Object', treeLike)) {
        tree = [treeLike]
    }
    const newTree = []
    for(let index in tree) {
        let item = tree[index]
        newTree[index] = func(item)
        if(item.children?.length) {
            newTree[index].children = treeMap(item.children, func)
        }
    }
    return newTree
}

/**
 * 遍历树上的点
 */
export function treeForEach(treeLike, func) {
    let tree = []
    if(isType('Array', treeLike)) {
        tree = treeLike
    }else if(isType('Object', treeLike)) {
        tree = [treeLike]
    }
    for(let index in tree) {
        let item = tree[index]
        func(item)
        if(item.children?.length) {
            treeForEach(item.children, func)
        }
    }
}

/**
 * 删除树上的点，首个匹配
 */
export function treeDel(tree: dynamicObj[], func) {
    let parent = treeFindParent(tree, func, {children: tree})
    let index = parent.children.findIndex(func)
    return parent.children.splice(Number(index), 1)
}

/**
 * 寻找叶子对象
 * @param obj
 * @param leafKey
 */
export function findLeaf(obj, leafKey) {
    if(obj?.hasOwnProperty && obj.hasOwnProperty(leafKey) || obj[leafKey]) {
        return findLeaf(obj[leafKey], leafKey)
    }else {
        return obj
    }
}

export function forkProp(obj, leafKey, propName) {
    if(obj?.hasOwnProperty && obj.hasOwnProperty(propName)) {
        return obj[propName]
    }else if(obj?.hasOwnProperty && obj.hasOwnProperty(leafKey) || obj[leafKey]) {
        return forkProp(obj[leafKey], leafKey, propName)
    }else {
        return null
    }
}

/**
 * 维表转树
 * @param dimList
 * @param dimLink
 * @param dimMap
 */
export function dim2Tree(dimList, dimLink, dimMap) {
    let filedSort = [];
    if (dimLink.length) {
        for (let propName of dimLink) {
            if (!propName) continue;
            let match = dimMap.find(item => item.propName === propName);
            filedSort.push(match);
        }
    }
    let dataTreeOrg = [];
    for (let r of dimList) {
        for (let linkIndexStr in filedSort) {
            let linkIndex = Number(linkIndexStr)
            let node = { id: '', parentId: '', label: '' };
            for (let i = 0; i <= linkIndex; i++) {
                node.id += r[filedSort[i].propFieldName];
                if (linkIndex > 0 && i > 0) node.parentId += r[filedSort[i - 1].propFieldName];
            }
            if (linkIndex == 0) node.parentId = '-1';
            node.label = r[filedSort[linkIndex].textFieldName];
            dataTreeOrg.push(node);
        }
    }
    dataTreeOrg = uniqBy(item => item.id, dataTreeOrg);
    return list2Tree(dataTreeOrg);
}

/**
 * 树筛选（包含父节点）
 * @param treeLike
 * @param func
 */
export function treeFilter(treeLike, func) {
    const list = tree2List(treeLike)
    setParentIds4List(list)
    const res = list.filter(func)
    const resParentIds = res.map(item => item._parentIds).flat()
    const res2 = list.filter(item => resParentIds.includes(item.id))
    return list2Tree(res2)
}

/**
 * 树转平铺
 * @param treeLike
 * @param list
 */
export function tree2List(treeLike, list = []) {
    let tree = []
    if(isType('Array', treeLike)) {
        tree = treeLike
    }else if(isType('Object', treeLike)) {
        tree = [treeLike]
    }
    for(let item of tree) {
        list.push(item)
        if(item.children?.length) {
            tree2List(item.children, list)
        }
    }
    return list
}

export default {
    list2Tree, setParentIds4List, treeFind, treeDel, treeMap, treeFindParent, findLeaf
}
